import { ElLoading , ElMessage } from 'element-plus'

let loading

// 开启加载动画
function startLoading() {
    loading = ElLoading .service({
        lock: true,
        text: '正在请求后台 ...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
    })
}
// 关闭加载动画
function endLoading() {
    loading.close()
}

const axiosUtil = {
    configInterceptors : function (axiosInst) {
        // 请求拦截器（前置）
        axiosInst.interceptors.request.use(config => {
            // 加载
            startLoading()
            // if (localStorage.eleToken)
            //   config.headers.Authorization = localStorage.eleToken
            return config
        }, error => {
            endLoading();
            ElMessage({type: 'error', message: '请求拦截器：请求错误！', duration: 1500})
            return Promise.reject(error)
        })

        // 响应拦截（后置）
        axiosInst.interceptors.response.use(response => {
            endLoading();
            try {
                if (response.data) {
                    return response.data;
                } else {
                    ElMessage.warning('没有返回任何数据: data = null');
                }
            } catch (e) {
                ElMessage.error('不存在 data 参数');
            }
            return null;
        }, err => {
            endLoading();
            if (err && err.response) {
                switch (err.response.status) {
                    case 400: err.message = '请求错误(400)'; break;
                    case 401: err.message = 'Token过期(401)'; break; // return history.push('/login'); break;
                    case 403: err.message = '拒绝访问(403)'; break;
                    case 404: err.message = '请求出错(404)'; break;
                    case 408: err.message = '请求超时(408)'; break;
                    case 500: err.message = '服务器错误(500)'; break;
                    case 501: err.message = '服务未实现(501)'; break;
                    case 502: err.message = '网络错误(502)'; break;
                    case 503: err.message = '服务不可用(503)'; break;
                    case 504: err.message = '网络超时(504)'; break;
                    case 505: err.message = 'HTTP版本不受支持(505)'; break;
                    default: err.message = `连接出错(${err.response.status})!`;
                }
            } else {
                err.message = '连接服务器失败!'
            }
            ElMessage.error(err.message);
            return Promise.reject(err);
        });
    },
    // 对 api 进行 axios 封装
    packAPI: function (api, axiosInst) {
        // 建立 key 到 value 的映射
        //      key -> roleAPI.key
        //      value -> obj{method, url}
        let req = {}
        for (let k in api) {
            let apiObj = api[k]
            /*
                params, // 请求参数 get、delete：url；put、post、patch：data
                pathParams = [] // 路径 url
                isFormData = false, // 标记是否为 form data 数据
                config = {} // 配置参数
             */
            req[k] = async function (params, pathParams = [], isFormData = false, config = {}) {
                let newParams
                let url = apiObj.url
                // content-type 是否是 form data 的判断
                if (params && isFormData) {
                    newParams = new FormData()
                    for (let p in params)
                        newParams.append(p, params[p])
                } else {
                    newParams = params
                }

                // 将路径参数加到 url path
                if (pathParams && pathParams.length > 0) {
                    for (let i = 0; i < pathParams.length; i++)
                        url += ('/' + pathParams[i])
                }

                let response = {}
                // 不用请求方法的枚举
                let method = apiObj.method.toLowerCase()
                switch (method) {
                    case 'get' :
                    case 'delete' :
                        config.params = newParams
                        // axios 里定义的 method 都是小写的
                        response = await axiosInst[method](url, config)
                        break
                    case 'post' :
                    case 'put' :
                    case 'patch' :
                        response = await axiosInst[method](url, newParams, config)
                        break
                    default:
                }
                return response
            }
        }
        // 返回封装后的结果
        return req
    }
}

export default axiosUtil

